#ifndef __WIZ_BNF_API_HPP__SHANHAOBO_19800429__
#define __WIZ_BNF_API_HPP__SHANHAOBO_19800429__

/// Backus-Naur Form
#include "./WizBNFScanner.hpp"
#include "./WizBNFMatch.hpp"

#include "./Parser/WizBNFParserSkipper.hpp"

namespace Wiz
{
    namespace BNF
    {
        ///////////////////////////////////////////////////////////////////////////
        //
        //  Generic parse function
        //
        ///////////////////////////////////////////////////////////////////////////
        template <typename IteratorT, typename DerivedT>
        ::Wiz::BNF::Info::Type<IteratorT> Parse
        (
            IteratorT const&                            Frst,
            IteratorT const&                            Lst,
            ::Wiz::BNF::Parser::Type<DerivedT> const&   Prsr
        )
        {
            IteratorT Curr = Frst;
            ::Wiz::BNF::Scanner::Type<IteratorT, ::Wiz::BNF::Policy::Scanner<>> Scan(Curr, Lst);
            ::Wiz::BNF::Match::Type<::Wiz::Null::Type> Hit = Prsr.Derived().Parse(Scan);
            return ::Wiz::BNF::Info::Type<IteratorT>(Curr, Hit, Hit && (Curr == Lst), Hit.Length());
        }

        ///////////////////////////////////////////////////////////////////////////
        //
        //  Parse function for null terminated strings
        //
        ///////////////////////////////////////////////////////////////////////////
        template <typename CharT, typename DerivedT>
        ::Wiz::BNF::Info::Type<CharT const * const>
        Parse
        (
            CharT const* const                          StrPtr,
            ::Wiz::BNF::Parser::Type<DerivedT> const&   Prsr
        )
        {
            return ::Wiz::BNF::Parse(StrPtr, ::Wiz::CStr::GetLast(StrPtr), Prsr);
        }
        //////////////////////////////////////////////////////////////////////////
        //
        // Generic parse function using the skippers
        //
        //////////////////////////////////////////////////////////////////////////
        template <typename IteratorT, typename ParserT, typename SkipT>
        WIZ_INLINE ::Wiz::BNF::Info::Type<IteratorT>
        Parse
        (
            IteratorT const&                            Frst,
            IteratorT const&                            Lst,
            ::Wiz::BNF::Parser::Type<ParserT> const&    Prsr,
            ::Wiz::BNF::Parser::Type<SkipT> const&      Skp
        )
        {
            return ::Wiz::BNF::Skipper::Phrase<SkipT>::Parse(Frst, Lst, Prsr.Derived(), Skp.Derived());
        }
        ///////////////////////////////////////////////////////////////////////////
        //
        //  Parse function for null terminated strings using the skippers
        //
        ///////////////////////////////////////////////////////////////////////////
        template <typename CharT, typename ParserT, typename SkipT>
        WIZ_INLINE ::Wiz::BNF::Info::Type<CharT const * const>
        Parse
        (
            CharT const * const                         StrPtr,
            ::Wiz::BNF::Parser::Type<ParserT> const&    Prsr,
            ::Wiz::BNF::Parser::Type<SkipT> const&      Skp
        )
        {
            return ::Wiz::BNF::Parse(StrPtr, ::Wiz::CStr::GetLast(StrPtr), Prsr, Skp);
        }
    } /// end of namespace BNF
} /// end of namespace Wiz

#endif /*__WIZ_BNF_API_HPP__SHANHAOBO_19800429__*/
